﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;

namespace Agile.Engine.Utils
{
    public class DataUtils
    {
        /// <summary>
        /// 类型转换泛型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="defaultValue"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T Parse<T>(T defaultValue, object value)
            where T : struct
        {

            if (value == null || value == DBNull.Value || string.IsNullOrEmpty(value.ToString()))
            {
                return defaultValue;
            }

            //枚举类型
            if (value.GetType().IsEnum)
            {
                var def = default(T);

                return (Enum.TryParse(value.ToString(), out def)) ? def : defaultValue;
            }

            //值类型
            else if (value.GetType().IsValueType)
            {
                var method = Spring.Util.ReflectionUtils.GetMethod(typeof(T), "Parse", new Type[] { typeof(string) });
                if (method == null) return defaultValue;
                return (T)method.Invoke(defaultValue, new object[] { value.ToString() });
            }

            return defaultValue;
        }

        /// <summary>
        /// datarow 转换到 hashtable
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static Hashtable ToHashTable(DataRow row)
        {
            Hashtable model = new Hashtable();
            foreach (DataColumn dc in row.Table.Columns)
            {
                model[dc.ColumnName] = row[dc.ColumnName];
            }
            return model;
        }

        /// <summary>
        /// datatable 结构 转换到 Hashtable
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static Hashtable ToHashTableSchema(DataTable dt)
        {
            Hashtable model = new Hashtable();
            foreach (DataColumn dc in dt.Columns)
            {
                model[dc.ColumnName] = string.Empty;
            }
            return model;
        }

        /// <summary>
        /// 查询data中指定field的value存在的所有行
        /// </summary>
        /// <param name="data"></param>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DataRow[] ScalarRow(DataTable data, string field, object value)
        {
            string digit = "{0}={1}";
            string str = "{0}='{1}'";
            var filter =
                (value.GetType() == typeof(System.String) || value.GetType() == typeof(DateTime))
                ? string.Format(str, field, value)
                : string.Format(digit, field, value);
            var exits = data.Select(filter);

            if (exits.Count() > 0)
            {
                return exits.ToArray();
            }
            return null;
        }

        public static DataTable Minus(DataTable a, DataTable b, string filed)
        {
            ///新表初始化结构
            DataTable newData = new DataTable(b.TableName);
            foreach (DataColumn d in b.Columns)
            {
                newData.Columns.Add(new DataColumn(d.ColumnName, d.DataType));
            }

            string filter = GetFilterFormat(newData.Columns[filed].DataType);

            IEnumerable<System.Data.DataRow> dataEnumerable = a.Rows.Cast<System.Data.DataRow>();
            //a表循环，b表获取，填入新表
            System.Threading.Tasks.Parallel.ForEach(dataEnumerable, (row) =>
            {
                var temp = b.Select(string.Format(filter, filed, row[filed]));
                //b表不存在
                if (temp.Length == 0)
                {
                    var newRow = newData.NewRow();
                    newRow.ItemArray = row.ItemArray;
                    newData.Rows.Add(newRow);
                }
            });

            return newData;

        }

        public static string GetFilterFormat(Type type)
        {
            string digit = "{0}={1}";
            string str = "{0}='{1}'";
            return
                (type == typeof(System.String) || type == typeof(DateTime))
                ? str
                : digit;

        }

        /// <summary>
        /// hashtable转换为过滤语句
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string ToFilter(IDictionary model)
        {
            List<string> filter = new List<string>();
            foreach (DictionaryEntry entry in model)
            {
                ///值不为空时
                if (!StringUtils.IsEmpty(entry.Value))
                {
                    ///取格式
                    var format = GetFilterFormat(entry.Value.GetType());

                    filter.Add(string.Format(format, entry.Key, entry.Value));
                }
            }

            if (filter.Count > 0)
            {
                return  string.Join(" AND ", filter.ToArray());
            }
            return string.Empty;
        }

        /// <summary>
        /// 数据行转过滤语句
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static string ToFilter(DataRow row)
        {
            return ToFilter(ToHashTable(row));
        }

        /// <summary>
        /// 指定字段转换到field in ()
        /// </summary>
        /// <param name="data">数据行</param>
        /// <param name="field">执行字段</param>
        /// <returns></returns>
        public static string ToFilter(DataRow[] data, string field, bool isDigit = false)
        {
            List<string> filter = new List<string>();

            foreach (var d in data)
            {
                filter.Add(d[field].ToString());
            }

            var format1 = " {0} in ({1})";
            var format2 = " {0} in ('{1}')";
            return string.Format(
                (isDigit ? format1 : format2),
                field,
                string.Join((isDigit ? "," : "','"), filter.ToArray()));
        }

        public static Hashtable ToEditModel(string key, params DataRow[] data)
        {
            Hashtable model = new Hashtable();
            model[key] = data.CopyToDataTable();
            return model;
        }
    }
}
